﻿<!--
> Muaz Khan     - https://github.com/muaz-khan 
> MIT License   - https://www.webrtc-experiment.com/licence/
> Documentation - https://github.com/muaz-khan/WebRTC-Experiment/tree/master/part-of-screen-sharing
-->
<!DOCTYPE html>
<html lang="en">
    <head>
        <script>
            if(!location.hash.replace('#', '').length) {
                location.href = location.href.split('#')[0] + '#' + (Math.random() * 100).toString().replace('.', '');
                location.reload();
            }
        </script>
        
        <title>Part of screen sharing using WebRTC Data Channel | Muaz Khan</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
        <link rel="author" type="text/html" href="https://plus.google.com/100325991024054712503">
        <meta name="author" content="Muaz Khan">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <link href="https://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet" type="text/css" />
        <link rel="stylesheet" href="https://www.webrtc-experiment.com/style.css">
        <style>
			input[type=text] {
				border: 1px solid black;
				font-family: inherit;
				font-size: 1em;
				margin: .1em .3em;
				outline: none;
				padding: .1em .2em;
				width: 97%;
			}
			
			.share-me {
				background: #eee;
				border: 2px solid black;
				display: inline-block;
				padding: 1.2em;
				vertical-align: top;
			}

				.share-me:hover {
					background: rgb(211, 205, 205);
				}

			#second-div {
				border: 2px solid red;
			}

			#third-div {
				border: 2px solid blue;
			}

			input[type=checkbox], input[type=checkbox] ~ label {
				-webkit-user-select: none;
				cursor: pointer;
			}
			
			.overlay {
				position: absolute;
				background: rgba(56, 53, 53, 0.38);
			}
		</style>
        <script>
            document.createElement('article');
            document.createElement('footer');
        </script>
		
        <!-- DataChannel.js library -->
        <script src="https://www.webrtc-experiment.com/DataChannel.js"> </script>
        <script src="https://www.webrtc-experiment.com/socket.io.js"> </script>
		<script src="https://www.webrtc-experiment.com/screenshot.js"> </script>
    </head>

    <body>
        <article>
            <header style="text-align: center;">
                <h1>
					<a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/part-of-screen-sharing" target="_blank">Part of Screen Sharing</a>
					using 
                    <a href="https://github.com/muaz-khan/DataChannel" target="_blank">DataChannel.js</a>
                </h1>
                <p>
                    <a href="https://www.webrtc-experiment.com/">HOME</a>
                    <span> &copy; </span>
                    <a href="http://www.MuazKhan.com/" target="_blank">Muaz Khan</a>
                    
                    .
                    <a href="http://twitter.com/WebRTCWeb" target="_blank" title="Twitter profile for WebRTC Experiments">@WebRTCWeb</a>
                    
                    .
                    <a href="https://github.com/muaz-khan?tab=repositories" target="_blank" title="Github Profile">Github</a>
                    
                    .
                    <a href="https://github.com/muaz-khan/WebRTC-Experiment/issues?state=open" target="_blank">Latest issues</a>
                    
                    .
                    <a href="https://github.com/muaz-khan/WebRTC-Experiment/commits/master" target="_blank">What's New?</a>
                </p>
            </header>

            <div class="github-stargazers"></div>
		
            <!-- just copy this <section> and next script -->
            <section class="experiment">
                <section>
                    <h2 style="border: 0; padding-left: .5em;">Open New DataChannel Connection</h2>
                    <button id="open-channel">Open</button>
                </section>

                <table style="width: 100%;" id="channels-list"></table>
            </section>
			
			<section class="experiment" style="overflow:hidden;">
				<div class="overlay" title="First of all; you should open data connection."></div>
				<div id="first-div" class="share-me" contenteditable title="Tick checkbox to share this DIV">
					<h2>First DIV</h2>

					<br />
					<input type="checkbox" id="share-div-1">
					<label for="share-div-1">Share DIV Number 1</label>
				</div>
				<div id="second-div" class="share-me" contenteditable title="Tick checkbox to share this DIV">
					<h2>Second DIV</h2>

					<br />
					<input type="checkbox" id="share-div-2">
					<label for="share-div-2">Share DIV Number 2</label>
				</div>
				<div id="third-div" class="share-me" contenteditable title="Tick checkbox to share this DIV">
					<h2>Third DIV</h2>

					<br />
					<input type="checkbox" id="share-div-3">
					<label for="share-div-3">Share DIV Number 3</label>
				</div>
			</section>
			
			<script>
					var overlay = document.querySelector('.overlay');
					overlay.style.width = overlay.parentNode.clientWidth + 'px';
					overlay.style.height = document.querySelector('#first-div').clientHeight + 'px';
				</script>
			
			<section class="experiment">
				<div title="Stop sharing your DIVs" style="border-bottom: 0;color: red;float:right;">
					<input type="checkbox" id="pause">
					<label for="pause">Pause Sharing</label>
				</div>

				<script>
					var pause = document.getElementById('pause');
					pause.onchange = function () {
						isShareDIV = !this.checked;
					};
				</script>
				
				<h2 class="header">Shared DIVs will be visible here ↓</h2>
				<div id="shared-parts-of-screen-preview" title="Your or your friend's shared DIVs are visible here." style="padding:1.2em;"></div>
			</section>
			
			<script>
            function find(id) {
                return document.getElementById(id);
            }

            var shareFirstDIV = find('share-div-1'),
                shareSecondDIV = find('share-div-2'),
                shareThirdDIV = find('share-div-3');

            shareFirstDIV.onchange = shareSecondDIV.onchange = shareThirdDIV.onchange = onchange;

            function onchange(input) {
                input = input || this;
                var parent = input.parentNode;

                if (input.checked) {
                    hide(true);
                    parent.style.display = 'inline-block';
                } else hide(false);

                if (input.checked) {
                    uncheckAll();
                    input.checked = true;
                }

                window.elementToShare = parent;
                if (!isShareDIV) {
                    isShareDIV = true;
                    pause.checked = false;
                    shareDIV();
                }

                if (!input.checked) {
                    isShareDIV = false;
                    pause.checked = true;
                }
            }

            function uncheckAll() {
                shareFirstDIV.checked =
                    shareSecondDIV.checked =
                        shareThirdDIV.checked = false;
            }

            function hide(isHide) {
                shareFirstDIV.parentNode.style.display =
                    shareSecondDIV.parentNode.style.display =
                        shareThirdDIV.parentNode.style.display = isHide ? 'none' : 'inline-block';
            }

            var shareMeDIVs = document.querySelectorAll('.share-me');
            for (var i = 0; i < shareMeDIVs.length; i++) {
                shareMeDIVs[i].onclick = function () {
                    if (!window.IsDataChannelOpened) {
                        alert('WebRTC Data Channel connection is not opened.');
                        return;
                    }
                    var input = this.querySelector('input');
                    input.checked = true;
                    onchange(input);
                };
            }
        </script>
        <!-- this script is taking screenshot and transmitting them over webrtc data channels -->
        <script>
            var isShareDIV = false;

            function shareDIV() {
                if (!isShareDIV) {
                    setTimeout(shareDIV, 1000);
                    return;
                }
                html2canvas(window.elementToShare, {
                    onrendered: function (canvas) {
                        var screenshot = canvas.toDataURL('image/webp', 1);
                        channel.send({
                            userID: userID,
                            screenshot: screenshot
                        });

                        if (!!navigator.webkitGetUserMedia) setTimeout(shareDIV, 5000);
                        else setTimeout(shareDIV, 10);
                    }
                });
            }
        </script>
		
		<!-- this script is getting screenshot shared with you -->
        <script>
            var sharedPartsOfScreenPreview = document.getElementById('shared-parts-of-screen-preview');

            function getNewImage(id) {
                var image = new Image();
                image.id = id;

                sharedPartsOfScreenPreview.insertBefore(image, sharedPartsOfScreenPreview.firstChild);
                return image;
            }

            function onMessage(data) {
                if (!data.screenshot) return;
                var image = document.getElementById(data.userID);
                if (!image) image = getNewImage(data.userID);
                image.src = data.screenshot;
            }

            window.userID = Math.round(Math.random() * 60535) + 500000;
        </script>
		
            <script>
                var channel = new DataChannel(); // DataChannel.js

                // https://github.com/muaz-khan/WebRTC-Experiment/tree/master/socketio-over-nodejs
                var SIGNALING_SERVER = 'https://socketio-over-nodejs2.herokuapp.com:443/';
                channel.openSignalingChannel = function(config) {
                   var channel = config.channel || this.channel || 'default-namespace';
                   var sender = Math.round(Math.random() * 9999999999) + 9999999999;
                   
                   io.connect(SIGNALING_SERVER).emit('new-channel', {
                      channel: channel,
                      sender : sender
                   });
                   
                   var socket = io.connect(SIGNALING_SERVER + channel);
                   socket.channel = channel;
                   
                   socket.on('connect', function () {
                      if (config.callback) config.callback(socket);
                   });
                   
                   socket.send = function (message) {
                        socket.emit('message', {
                            sender: sender,
                            data  : message
                        });
                    };
                   
                   socket.on('message', config.onmessage);
                };

                // "ondatachannel" is fired for each new data channel
                channel.ondatachannel = function(channel00) {
                    var alreadyExist = document.getElementById(channel00.id);
                    if (alreadyExist) return;

                    var tr = document.createElement('tr');
                    tr.setAttribute('id', channel00.owner);
                    tr.innerHTML = '<td>' + channel00.id + '</td>' +
                        '<td><button class="join" id="' + channel00.id + '">Join</button></td>';

                    channelsList.insertBefore(tr, channelsList.firstChild);

                    // when someone clicks table-row; joining the relevant data channel
                    tr.onclick = function () {
                        
                        // manually joining a data channel
                        channel.join({
                            id: this.querySelector('.join').id,
                            owner: this.id
                        });
                        
                        channelsList.style.display = 'none';
                    };
                };

		        // a text message or data
                channel.onmessage = function(data, userid, latency) {
                    onMessage(data);

                    console.debug(userid, 'posted', data);
                    console.log('latency:', latency, 'ms');
                };

		        // on data connection gets open
                channel.onopen = function() {
                    window.IsDataChannelOpened = true;
					overlay.style.display = 'none';
                };

                var channelsList = document.getElementById('channels-list');

                // data-channel name to uniquely identify your connection
                var channel_name = location.href.replace(/\/|:|#|%|\.|\[|\]/g, '');

                document.getElementById('open-channel').onclick = function () {
                    this.disabled = true;
                    
                    // opening new data channel
                    channel.open(channel_name);
                };

                // searching for existing channels
                channel.connect(channel_name);
            </script>
			
			<section class="experiment">
				<h2 class="header">How to use this experiment?</h2>
                <ol>
					<li>Setup data connection.</li>
					<li>Click a DIV to share.</li>
					<li>Change DIV's content; all DIVs are edit-able.</li>
				</ol>
            </section>
			
			<section class="experiment">
                <ol>
					<li>Sharing <strong>part of the screen</strong> or <strong>region of screen</strong> (i.e. a DIV, SECTION, ARTICLE or ASIDE)... not the entire screen!</li>
					<li>Everything inside that DIV is <strong>synchronized</strong> in realtime.</li>
					<li>Works fine on all modern web browsers supporting WebRTC Data Channels.</li>
				</ol>
            </section>
			
			<section class="experiment">
                <h2 class="header">How?</h2>
                <ol>
					<li>Share screenshots of the entire DIV, ASIDE or BODY element in realtime!</li>
					<li>Using WebRTC Data Channel to transmit screenshots in realtime!</li>
					<li>It is better to "<strong>pause sharing</strong>" to scroll down and see others' shared regions.</li>
					<li>It supports multi-user connectivity too! Hmm! i.e. you can share region of screen with many friends!</li>
				</ol>
            </section>
			
			<section class="experiment">
				<h2 style="display: block; font-weight: normal; text-align: center;"
					title="Using RTCDataChannel APIs to share your DIVs' screenshots. It is super-fast and 100% realtime on Firefox!">Try <a href="https://www.webrtc-experiment.com/part-of-screen-sharing/" target="_blank">Part
								of Screen Sharing using Firebase</a>
				</h2>
			</section>
			
			<section class="experiment">
				<pre>
&lt;script src="https://www.webrtc-experiment.com/screenshot.js"&gt;&lt;/script&gt;
&lt;script&gt;
var divToShare = document.querySelector('div');
html2canvas(divToShare, {
    onrendered: function (canvas) {
        var screenshot = canvas.toDataURL();
        // image.src = screenshot;
        // context.drawImage(screenshot, x, y, width, height);
        // firebase.push(screenshot);
        // pubnub.send(screenshot);
        // socketio.send(screenshot);
        // signaler.send(screenshot);
        // window.open(screenshot);
    }
});

/*
 <h2>Note:</h2>
 Put above code in a function; use "requestAnimationFrame" to loop the function
 and post/transmit DataURL in realtime!

 <h2>What above code will do?</h2>
 Above code will take screenshot of the DIV or other HTML element and return you
 and image. You can preview image to render in IMG element or draw to Canvas2D.
 */
&lt;/script&gt;
</pre>
			</section>
            
            <section class="experiment">
				<h2 style="display: block; text-align: center;"><a
					href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/part-of-screen-sharing" target="_blank">Part of
                                                               screen sharing is open-sourced on Github!</a></h2>
			</section>
            
            <section class="experiment">
                <h2 class="header" id="feedback">Feedback</h2>
                <div>
                    <textarea id="message" style="border: 1px solid rgb(189, 189, 189); height: 8em; margin: .2em; outline: none; resize: vertical; width: 98%;" placeholder="Have any message? Suggestions or something went wrong?"></textarea>
                </div>
                <button id="send-message" style="font-size: 1em;">Send Message</button><small style="margin-left: 1em;">Enter your email too; if you want "direct" reply!</small>
            </section>
			
			<section class="experiment own-widgets latest-commits">
                <h2 class="header" id="updates" style="color: red; padding-bottom: .1em;"><a href="https://github.com/muaz-khan/WebRTC-Experiment/commits/master" target="_blank">Latest Updates</a></h2>
                <div id="github-commits"></div>
            </section>
        </article>
        
        <a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/part-of-screen-sharing" class="fork-left"></a>
        
         <footer>
            <p>
                <a href="https://www.webrtc-experiment.com/">WebRTC Experiments</a>
                © <a href="https://plus.google.com/+MuazKhan" rel="author" target="_blank">Muaz Khan</a>
                <a href="mailto:muazkh@gmail.com" target="_blank">muazkh@gmail.com</a>
            </p>
        </footer>
	
        <!-- commits.js is useless for you! -->
        <script src="https://www.webrtc-experiment.com/commits.js" async> </script>
    </body>
</html>
